package com.aquarium.ui;

import java.util.Observable;
import java.util.Observer;

import com.aquarium.R;
import com.aquarium.alias.AliasManager;
import com.aquarium.bt.BTManager;
import com.aquarium.bt.DataInterpreter;
import com.aquarium.bt.DataStruct;
import com.aquarium.config.BTCommand;

import android.R.anim;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.MaskFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.Toast;

public class AliasSettingActivity extends Activity implements Observer {

	private static final String TAG = "AliasSettingActivity";

	private static final int MESSAGE_SHOW_REMOTE_DEVICES = 0x10;
	private static final int MESSAGE_DISCOVERY_FINISHED = 0x11;
	private static final int MESSAGE_REQUEST_AUTHENTICATION = 0x12;
	private static final int MESSAGE_START_DISCOVERING = 0x13;
	private static final int MESSAGE_START_CONNECTING = 0x14;
	private static final int MESSAGE_RECEIVE_DATA_TIMEOUT = 0x15;
	private static final int MESSAGE_AUTHENTICATION_SUCCESS = 0x16;
	private static final int MESSAGE_AUTHENTICATION_FAIL = 0x17;
	private static final int MESSAGE_CONNECT_FAIL = 0x18;
	private static final int MESSAGE_IN_PROGRESS = 0x19;

	/**
	 * timeout value of waiting for controller's reply (ms)
	 */
	private static final int TIMEOUT_VALUE = 5000;

	private Context mContext;

	private ImageView mOkButton;
	private ImageView mCancelButton;

	/**
	 * the dialog to block user when communication is in progress.
	 */
	private ProgressDialog mProgressDialog;

	private Spinner[] mSpinner = new Spinner[6];
	private int[] mSelectedId;
	private byte[] mCommand;

	private ArrayAdapter<CharSequence> mArrayAdapter;

	private AliasManager mAliasManager;
	private BTManager mBtManager;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.controller_setting);

		mContext = AliasSettingActivity.this;
		mAliasManager = AliasManager.getInstance(mContext);
		mBtManager = BTManager.getInstance();

		mOkButton = (ImageView) findViewById(R.id.ok);
		mCancelButton = (ImageView) findViewById(R.id.cancel);

		mSpinner[0] = (Spinner) findViewById(R.id.controllers_spinner1);
		mSpinner[1] = (Spinner) findViewById(R.id.controllers_spinner2);
		mSpinner[2] = (Spinner) findViewById(R.id.controllers_spinner3);
		mSpinner[3] = (Spinner) findViewById(R.id.controllers_spinner4);
		mSpinner[4] = (Spinner) findViewById(R.id.controllers_spinner5);
		mSpinner[5] = (Spinner) findViewById(R.id.controllers_spinner6);

		mArrayAdapter = ArrayAdapter
				.createFromResource(mContext, R.array.controllers_array,
						android.R.layout.simple_spinner_item);

		mSelectedId = mAliasManager.getControllerType();

		for (int i = 0; i < 6; i++) {
			mSpinner[i].setAdapter(mArrayAdapter);
			mSpinner[i].setSelection(mSelectedId[i]);
		}

		mOkButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				for (int i = 0; i < 6; i++) {
					mSelectedId[i] = mSpinner[i].getSelectedItemPosition();

					// one controller only appear once.
					if (mSelectedId[i] != 0) {
						for (int j = 0; j < i; j++) {
							if (mSelectedId[i] == mSelectedId[j]) {
								Toast.makeText(
										mContext,
										getText(R.string.controller_duplication),
										Toast.LENGTH_SHORT).show();
								return;
							}
						}
					}
				}

				mBtManager.addObserver(AliasSettingActivity.this);

				sendData();

				// test code
				SystemClock.sleep(1000);
				mBtManager.receivePseudoData(mCommand);

				// mAliasManager.setSelectedId(mSelectedId);
				// finish();
			}
		});

		mCancelButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				finish();
			}
		});
	}

	private Handler mHandler = new Handler() {
		public void handleMessage(android.os.Message msg) {
			switch (msg.what) {
			case MESSAGE_IN_PROGRESS:
				showProgressDialog();
				break;
			case MESSAGE_RECEIVE_DATA_TIMEOUT:
				mProgressDialog.dismiss();
				showToast(getString(R.string.receive_data_timeout));
				break;
			case MESSAGE_AUTHENTICATION_SUCCESS:
				mProgressDialog.dismiss();
				showToast(getString(R.string.set_success));
				mAliasManager.setSelectedId(mSelectedId);
				finish();
				break;
			case MESSAGE_AUTHENTICATION_FAIL:
				mProgressDialog.dismiss();
				showToast(getString(R.string.set_fail));
				break;
			default:
				break;
			}
		};
	};

	private void showToast(String content) {
		Toast.makeText(mContext, content, Toast.LENGTH_SHORT).show();
	}

	private void showProgressDialog() {
		mProgressDialog = new ProgressDialog(mContext);
		mProgressDialog.setMessage(getText(R.string.please_wait));
		mProgressDialog.show();
	}

	@Override
	public boolean onKeyUp(int keyCode, KeyEvent event) {

		if (keyCode == KeyEvent.KEYCODE_BACK) {
			for (int i = 0; i < 6; i++) {
				if (mSelectedId[i] != mSpinner[i].getSelectedItemPosition()) {
					requestSaveSettings();
					return true;
				}
			}
		}

		return super.onKeyUp(keyCode, event);
	}

	private void requestSaveSettings() {
		AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
		LayoutInflater inflater = this.getLayoutInflater();
		final View view = inflater.inflate(R.layout.dialog_controller_setting,
				null);

		builder.setView(view)
				.setPositiveButton(R.string.save,
						new DialogInterface.OnClickListener() {
							@Override
							public void onClick(DialogInterface dialog, int id) {
								dialog.dismiss();
								sendData();
							}
						})
				.setNegativeButton(R.string.cancel,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface dialog, int id) {
								finish();
							}
						}).create().show();
	}

	private void sendData() {
		// send command to controller
		mCommand = BTCommand.getSetAliasCommand(mSelectedId);
		mBtManager.sendData(DataInterpreter.unpack(mCommand));

		mHandler.sendEmptyMessageDelayed(MESSAGE_RECEIVE_DATA_TIMEOUT,
				TIMEOUT_VALUE);
		mHandler.sendEmptyMessage(MESSAGE_IN_PROGRESS);
	}

	@Override
	public void update(Observable observable, Object data) {
		if (observable instanceof BTManager) {
			final DataStruct receivedData = (DataStruct) data;
			byte[] resposeData = DataInterpreter.pack(receivedData);

			if (receivedData.prefix == 0x5a && receivedData.id == 0x01
					&& receivedData.code == 0x67 && receivedData.length == 0x0c) {
				Log.d(TAG, "get responce data of set alias");
				mHandler.removeMessages(MESSAGE_RECEIVE_DATA_TIMEOUT);

				if (resposeData.length != mCommand.length) {
					mHandler.sendEmptyMessage(MESSAGE_AUTHENTICATION_FAIL);
					return;
				}
				for (int i = 0; i < resposeData.length; i++) {
					if (resposeData[i] != mCommand[i]) {
						mHandler.sendEmptyMessage(MESSAGE_AUTHENTICATION_FAIL);
						return;
					}
				}
				mHandler.sendEmptyMessage(MESSAGE_AUTHENTICATION_SUCCESS);

			}
		}

	}

}
